#include "basic_board.h"

static MotorLockStatus_t CurrectMotorStatus; // 当前电机状态

#if _UNLOCK_TYPE_ == _UNLOCK_MOTOR_

/**
 * @brief 配置使能管脚
 *
 */
static void Tim8837EnablePinConfiguration(void);

/**
 * @brief 配置电机正转管脚
 *
 */
static void Tim8837ForwardPinConfiguration(void);

/**
 * @brief 配置电机反转管脚
 *
 */
static void Tim8837ReversalPinConfiguration(void);

/**
 * @brief 设置电机使能管脚高电平
 *
 */
static void Tim8837SetEnablePinHightLevel(void);

/**
 * @brief 配置电机使能管脚低电平
 *
 */
static void Tim8837SetEnablePinLowLevel(void);

/**
 * @brief 设置电机正转管脚高电平
 *
 */
static void Tim8837SetForwardPinHightLevel(void);

/**
 * @brief 设置电机正转管脚低电平
 *
 */
static void Tim8837SetForwardPinLowLevel(void);

/**
 * @brief 设置电机反转管脚高电平
 *
 */
static void Tim8837SetReversalPinHightLevel(void);

/**
 * @brief 设置电机反转管脚低电平
 *
 */
static void Tim8837SetReversalPinLowLevel(void);

/**
 * @brief 设置电机使能管脚电平
 *
 * @param PinLevel - 管脚电平（true：高电平 false：低电平）
 */
static void Tim8837SetEnablePinLevel(bool PinLevel);

/**
 * @brief 设置电机正转管脚电平
 *
 * @param PinLevel - 管脚电平（true：高电平 false：低电平）
 */
static void Tim8837SetForwardPinLevel(bool PinLevel);

/**
 * @brief 设置电机反转管脚电平
 *
 * @param PinLevel - 管脚电平（true：高电平 false：低电平）
 */
static void Tim8837SetReversalPinLevel(bool PinLevel);

/**
 * @brief 电机驱动使能
 *
 */
static void Tim8837DriverEnable(void);

/**
 * @brief 电机驱动失能
 *
 */
static void Tim8837DriverDisable(void);

/**
 * @brief 电机待机
 *
 */
static void Tim8837IntoStandbyMode(void);

/**
 * @brief 电机正转
 *
 */
static void Tim8837IntoForwardMode(void);

/**
 * @brief 电机反转
 *
 */
static void Tim8837IntoReversalMode(void);

static Tim8837Status_t Tim8837Status; // 电机状态

static void Tim8837EnablePinConfiguration(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ModeCfg(TIM8837_EN_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_ModeCfg(TIM8837_EN_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ModeCfg(TIM8837_EN_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ModeCfg(TIM8837_EN_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ModeCfg(TIM8837_EN_PIN, GPIO_ModeOut_PP_20mA);
#endif

  Tim8837SetEnablePinLowLevel();
}

static void Tim8837ForwardPinConfiguration(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ModeCfg(TIM8837_FOR_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_ModeCfg(TIM8837_FOR_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ModeCfg(TIM8837_FOR_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ModeCfg(TIM8837_FOR_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ModeCfg(TIM8837_FOR_PIN, GPIO_ModeOut_PP_20mA);
#endif

  Tim8837SetForwardPinLowLevel();
}

static void Tim8837ReversalPinConfiguration(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ModeCfg(TIM8837_BAK_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_ModeCfg(TIM8837_BAK_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ModeCfg(TIM8837_BAK_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ModeCfg(TIM8837_BAK_PIN, GPIO_ModeOut_PP_20mA);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ModeCfg(TIM8837_BAK_PIN, GPIO_ModeOut_PP_20mA);
#endif

  Tim8837SetReversalPinLowLevel();
}

static void Tim8837SetEnablePinHightLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_SetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_SetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_SetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_SetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_SetBits(TIM8837_EN_PIN);
#endif
}

static void Tim8837SetEnablePinLowLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ResetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_ResetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ResetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ResetBits(TIM8837_EN_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ResetBits(TIM8837_EN_PIN);
#endif
}

static void Tim8837SetForwardPinHightLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_SetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_SetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_SetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_SetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_SetBits(TIM8837_FOR_PIN);
#endif
}

static void Tim8837SetForwardPinLowLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ResetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_ResetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ResetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ResetBits(TIM8837_FOR_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ResetBits(TIM8837_FOR_PIN);
#endif
}

static void Tim8837SetReversalPinHightLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_SetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_SetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_SetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_SetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_SetBits(TIM8837_BAK_PIN);
#endif
}

static void Tim8837SetReversalPinLowLevel(void)
{
#if _BOARD_TYPE_ == _6681_A_BOARD_
  GPIOB_ResetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _6681_B_BOARD_
  GPIOB_ResetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _M157_A_BOARD_
  GPIOB_ResetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _9905_A_BOARD_
  GPIOB_ResetBits(TIM8837_BAK_PIN);

#elif _BOARD_TYPE_ == _9905_B_BOARD_
  GPIOB_ResetBits(TIM8837_BAK_PIN);
#endif
}

static void Tim8837SetEnablePinLevel(bool PinLevel)
{
  (PinLevel == true) ? Tim8837SetEnablePinHightLevel() : Tim8837SetEnablePinLowLevel();
}

static void Tim8837SetForwardPinLevel(bool PinLevel)
{
  (PinLevel == true) ? Tim8837SetForwardPinHightLevel() : Tim8837SetForwardPinLowLevel();
}

static void Tim8837SetReversalPinLevel(bool PinLevel)
{
  (PinLevel == true) ? Tim8837SetReversalPinHightLevel() : Tim8837SetReversalPinLowLevel();
}

static void Tim8837DriverEnable(void)
{
  Tim8837SetEnablePinLevel(true);
}

static void Tim8837DriverDisable(void)
{
  Tim8837SetEnablePinLevel(false);
}

static void Tim8837IntoStandbyMode(void)
{
  Tim8837SetForwardPinLevel(false);
  Tim8837SetReversalPinLevel(false);
}

static void Tim8837IntoForwardMode(void)
{
  Tim8837SetForwardPinLevel(true);
  Tim8837SetReversalPinLevel(false);
}

static void Tim8837IntoReversalMode(void)
{
  Tim8837SetReversalPinLevel(true);
  Tim8837SetForwardPinLevel(false);
}

#else
/**
 * @brief 配置驱动管脚
 *
 */
static void RealyDriverConfiguration(void);

/**
 * @brief 配置驱动管脚高电平
 *
 */
static void RealyDriverPinHightLevel(void);

/**
 * @brief 配置驱动管脚低电平
 *
 */
static void RealyDriverPinLowLevel(void);

/**
 * @brief 设置继电器驱动管脚电平
 *
 * @param PinLevel - 管脚电平（true：高电平 false：低电平）
 */
static void SetRealyDriverPinLevel(bool PinLevel);

static RelayStatus_t RelayStatus = {0};

static void RealyDriverConfiguration(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  GPIOB_ModeCfg(BASIC_RELAY_CONTORL_PIN, GPIO_ModeOut_PP_20mA);
#endif
}

static void RealyDriverPinHightLevel(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  GPIOB_SetBits(BASIC_RELAY_CONTORL_PIN);
#endif
}

static void RealyDriverPinLowLevel(void)
{
#if _BOARD_TYPE_ == _DA01_A_BOARD_
  GPIOB_ResetBits(BASIC_RELAY_CONTORL_PIN);
#endif
}

static void SetRealyDriverPinLevel(bool PinLevel)
{
  (PinLevel == true) ? RealyDriverPinHightLevel() : RealyDriverPinLowLevel();
}

#endif

void MotorTaskCallback(void)
{
#if _UNLOCK_TYPE_ == _UNLOCK_MOTOR_
  switch (Tim8837Status)
  {
  case TIM8837_HARDWARE_STANDBY:
  {
    Tim8837Status = TIM8837_HARDWARE_REVERSAL;

    Tim8837IntoReversalMode();
    BasicDelayedStartMotorTask(BasicGetMoTorDriveTime());
  }
  break;

  case TIM8837_HARDWARE_FOREWARD:
  {
    Tim8837IntoStandbyMode();
    Tim8837Status = TIM8837_HARDWARE_STANDBY;
  }
  break;

  default:
  {
    CurrectMotorStatus = MOTOR_LOCK;
    Tim8837Status = TIM8837_HARDWARE_SLEEP;

    Tim8837IntoStandbyMode();
    Tim8837DriverDisable();
  }
  break;
  }

#else
  switch (RelayStatus)
  {
  case RELAY_HARDWARE_NORMAL_OPEN:
  {
    SetRealyDriverPinLevel(true);
    CurrectMotorStatus = MOTOR_NORMALLY_OPEN;
  }
  break;

  case RELAY_HARDWARE_UNLOCK:
  {
    SetRealyDriverPinLevel(true);
    CurrectMotorStatus = MOTOR_UNLOCKING;

    RelayStatus = RELAY_HARDWARE_LOCKED;
    BasicDelayedStartMotorTask(BasicGetUnlockHoldTime());
  }
  break;

  default:
  {
    SetRealyDriverPinLevel(false);
    CurrectMotorStatus = MOTOR_LOCK;
  }
  break;
  }
#endif
}

void UpdateMotorActionStatus(MotorLockStatus_t NewStatus)
{
#if _UNLOCK_TYPE_ == _UNLOCK_MOTOR_
  Tim8837DriverEnable();

  switch (NewStatus)
  {
  case MOTOR_NORMALLY_OPEN:
  {
    if (CurrectMotorStatus != MOTOR_NORMALLY_OPEN)
    {
      CurrectMotorStatus = MOTOR_NORMALLY_OPEN;
      Tim8837Status = TIM8837_HARDWARE_FOREWARD;

      Tim8837IntoForwardMode();
      BasicDelayedStartMotorTask(BasicGetMoTorDriveTime());
    }
  }
  break;

  case MOTOR_UNLOCKING:
  {
    if (CurrectMotorStatus != MOTOR_NORMALLY_OPEN)
    {
      CurrectMotorStatus = MOTOR_UNLOCKING;
      Tim8837Status = TIM8837_HARDWARE_FOREWARD;

      Tim8837IntoForwardMode();
      BasicDelayedStartMotorTask(BasicGetMoTorDriveTime());
    }
  }
  break;

  default:
  {
    CurrectMotorStatus = MOTOR_LOCK;
    Tim8837Status = TIM8837_HARDWARE_REVERSAL;

    Tim8837IntoReversalMode();
    BasicDelayedStartMotorTask(BasicGetMoTorDriveTime());
  }
  break;
  }

#else
  switch (NewStatus)
  {
  case MOTOR_NORMALLY_OPEN:
  {
    if (CurrectMotorStatus != MOTOR_NORMALLY_OPEN)
    {
      BasicStartMotorTaskNoWait();
      RelayStatus = RELAY_HARDWARE_NORMAL_OPEN;
    }
  }
  break;

  case MOTOR_UNLOCKING:
  {
    if (CurrectMotorStatus != MOTOR_NORMALLY_OPEN)
    {
      BasicStartMotorTaskNoWait();
      RelayStatus = RELAY_HARDWARE_UNLOCK;
    }
  }
  break;

  default:
  {
    BasicStartMotorTaskNoWait();
    RelayStatus = RELAY_HARDWARE_LOCKED;
  }
  break;
  }
#endif
}

MotorLockStatus_t GetMotorActionStatus(void)
{
  return CurrectMotorStatus;
}

void MotorPowerUpInitialization(void)
{
  CurrectMotorStatus = MOTOR_LOCK;

#if _UNLOCK_TYPE_ == _UNLOCK_MOTOR_
  Tim8837Status = TIM8837_HARDWARE_INIT;

  Tim8837DriverEnable();
  Tim8837IntoReversalMode();
  BasicDelayedStartMotorTask(BasicGetMoTorDriveTime());

#else
  SetRealyDriverPinLevel(false);
#endif
}

void MotorBoardInitialisation(void)
{
#if _UNLOCK_TYPE_ == _UNLOCK_MOTOR_
  Tim8837EnablePinConfiguration();
  Tim8837ForwardPinConfiguration();
  Tim8837ReversalPinConfiguration();

#else
  RealyDriverConfiguration();
#endif
}
